<!-- 计数合计器 -->
<template>
  <div class="input-number-group-container">
    <div class="input-number-group-content">
      <slot></slot>
    </div>
    <div
      class="input-number-group-summary"
      :style="{
        justifyContent: position === 'left' ? 'flex-start' : 'flex-end',
        borderTopStyle: showLine ? 'solid' : 'none'
      }"
    >
      <span
        class="summary-label"
        :style="{
          width: labelWidth ? `${labelWidth}px` : 'auto',
          textAlign: labelPosition === 'left' ? 'left' : 'right'
        }"
        >{{ label }}</span
      >
      <span class="summary-value">{{ totalValue }}{{ unit }}</span>
    </div>
  </div>
</template>

<script setup lang="ts">
defineOptions({ name: 'InputNumberGroup' })

// 接收外部传入的模型值
const props = defineProps({
  modelValue: {
    type: Number,
    default: 0
  },
  unit: {
    type: String,
    default: ''
  },
  label: {
    type: String,
    default: '合计：'
  },
  labelWidth: {
    type: Number,
    default: 100
  },
  labelPosition: {
    type: String,
    default: 'right'
  },
  showLine: {
    type: Boolean,
    default: true
  },
  position: {
    type: String,
    default: 'right'
  }
})

// 触发模型值更新事件
const emit = defineEmits(['update:modelValue'])

// 存储子组件的值
const childValues = ref<{ [key: string]: number }>({})

// 用于标识inputNumberGroup的唯一符号
const groupId = Symbol('inputNumberGroup')

// 注册子inputNumber组件
const registerChild = (id: string, initialValue: number = 0) => {
  childValues.value[id] = initialValue
  return (newValue: number) => {
    childValues.value[id] = newValue
  }
}

// 提供给子组件的上下文
provide('inputNumberGroup', {
  groupId,
  registerChild
})

// 计算总值
const totalValue = computed(() => {
  return Object.values(childValues.value).reduce((sum: number, value: number) => {
    return sum + (Number(value) || 0)
  }, 0)
})

// 监听总值变化，并向外发出事件更新表单值
watch(totalValue, (newValue) => {
  emit('update:modelValue', newValue)
})
</script>

<style lang="scss" scoped>
.input-number-group-container {
  position: relative;
  width: 100%;
  padding-bottom: 15px;
  // border: 1px dashed #dcdfe6;
  border-radius: 4px;
}

.input-number-group-content {
  margin-bottom: 10px;
}

.input-number-group-summary {
  display: flex;
  padding-top: 8px;
  padding-right: 15px;
  border-top: 1px solid #f0f0f0;
  justify-content: flex-end;
  align-items: center;
}

.summary-label {
  margin-right: 5px;
  font-size: 14px;
  color: #606266;
}

.summary-value {
  font-size: 16px;
  font-weight: bold;
  color: var(--el-color-primary);
}
</style>
